//编译原理实验-语法分析、语义分析，构建语法树
#include "Tree.h"
#include "malloc.h"

Node* createNode(char* name, NodeType nodeType, int lineno, int childNum, Node** children) {
    Node* res = (Node*)malloc(sizeof(Node));
    res->name = name; // 节点名字
    res->nodeType = nodeType; // 节点类型
    res->lineno = lineno; // 行号
    res->childNum = childNum; // 子节点个数
    res->children = children; // 子节点数组
    // 空串可能会向上传递
    int nullFlag = 1; // 1表示全空，0表示不全空
    for (int i = 0; i < res->childNum; i++)
        if ((res->children)[i]->nodeType != ENUM_SYN_NULL)  // 子节点不全空
            nullFlag = 0;
    if (nodeType == ENUM_SYN_NOT_NULL && nullFlag == 1) // 如果是非空节点，但是全空
        res->nodeType = ENUM_SYN_NULL;
    return res;
}

void printTree(Node* root, int depth) {
    // 打印缩进
    if (root->nodeType != ENUM_SYN_NULL)
        for (int i = 0; i < depth; i++)
            printf("  ");
    // 根据节点类型选择打印该节点的部分信息
    switch (root->nodeType) {
        case ENUM_SYN_NOT_NULL: // 非空节点
            printf("%s (%d)\n", root->name, root->lineno);
            break;
        case ENUM_SYN_NULL: // 空节点
            break;
        case ENUM_LEX_ID: // 标识符
            printf("%s: %s\n", root->name, root->strVal);
            break;
        case ENUM_LEX_TYPE: // 类型
            printf("%s: %s\n", root->name, root->strVal);
            break;
        case ENUM_LEX_INT:  // 整数
            printf("%s: %d\n", root->name, root->intVal);
            break;
        case ENUM_LEX_FLOAT:  // 浮点数
            printf("%s: %f\n", root->name, root->floatVal);
            break;
        case ENUM_LEX_OTHER:  // 其他
            printf("%s\n", root->name);
            break;
    }
    // 递归打印子节点
    for (int i = 0; i < root->childNum; i++) {
        printTree(root->children[i], depth + 1);
    }
}